mergeInto(LibraryManager.library, {
    JSEnvInit: function () {
        var global = typeof window !== 'undefined' ? window : typeof GameGlobal !== 'undefined' ? GameGlobal : typeof globalThis !== 'undefined' ? globalThis : {};
        global.window = typeof window !== 'undefined' ? window : global;
        const zs = global.zs = global.zs || {};
        zs.env = typeof global.bl !== 'undefined' ? global.bl : typeof global.ks !== 'undefined' ? global.ks : typeof global.tt !== 'undefined' ? global.tt : typeof global.wx !== 'undefined' ? global.wx : null;
        zs.pf = typeof global.bl !== 'undefined' ? 'bili' : typeof global.ks !== 'undefined' ? 'ks' : typeof global.tt !== 'undefined' ? 'tt' : typeof global.wx !== 'undefined' ? 'wx' : 'web';
        zs.unity = {};
        zs.unity.ads = {};
        zs.unity.feedStatusChange = null;
        zs.unity.str2utf8 = function (str) {
            if (null == str) {
                str = '';
            }
            var bufferSize = lengthBytesUTF8(str) + 1;
            var buffer = _malloc(bufferSize);
            stringToUTF8(str, buffer, bufferSize);
            return buffer;
        };

        var anySendMessage = null;
        function getSendMessage() {
            if (anySendMessage) {
                return anySendMessage;
            }
            if (zs.pf == "wx" || zs.pf == 'bili') {
                anySendMessage = SendMessage
            } else if (zs.pf == "tt") {
                anySendMessage = globalUnityInstance.SendMessage
            }
            if (!anySendMessage && window.unityInstance) {
                anySendMessage = window.unityInstance.SendMessage
            }
            return anySendMessage;
        }

        zs.unity.sendMessage = function (funcName, obj) {
            const sendMessage = getSendMessage();
            if (!sendMessage) {
                setTimeout(function () {
                    zs.unity.sendMessage(funcName, obj);
                }, 200);
                return;
            }
            if (!obj) {
                sendMessage('SeegSdkUnityMono', funcName);
            } else {
                var str = JSON.stringify(obj);
                sendMessage('SeegSdkUnityMono', funcName, str);
            }
        };

        var USER_DATA_PATH = '';
        if (zs.pf == 'tt') {
            USER_DATA_PATH = 'ttfile://user'
        } if (null != zs.env) {
            USER_DATA_PATH = zs.env.env.USER_DATA_PATH
        }
        var ret = {
            USER_DATA_PATH,
            pfEnv: zs.pf
        };
        if (zs.gameConfig) {
            Object.assign(ret, zs.gameConfig);
        }
        if (zs.pf == 'bili') {
            function dealAccountInfo(accountInfo) {
                if (null == accountInfo) {
                    return;
                }
                if (!accountInfo.miniProgram) {
                    accountInfo.miniProgram = {
                        envVersion: 'release'
                    }
                    zs.unity.accountInfoStr = JSON.stringify(accountInfo);
                    return;
                }
                let envVersion = accountInfo.miniProgram.envVersion;
                if ('dev' === envVersion) {
                    accountInfo.miniProgram.envVersion = 'develop';
                } else if ('predev' === envVersion) {
                    accountInfo.miniProgram.envVersion = 'trial';
                } else {
                    accountInfo.miniProgram.envVersion = 'release';
                }
                zs.unity.accountInfoStr = JSON.stringify(accountInfo);
            }
            try {
                dealAccountInfo(bl.getAccountInfoSync());
            } catch (e) { }
            if (null == zs.unity.accountInfoStr) {
                bl.getAccountInfo({
                    success: (res) => {
                        dealAccountInfo(res);
                    }
                });
            }
        }

        return zs.unity.str2utf8(JSON.stringify(ret));
    },

    JSOnFeedStatusChange: function () {
        if (zs.pf != 'tt') {
            return;
        }

        if (null != zs.unity.feedStatusChange) {
            return;
        }

        function checkFeedGameNew(ret) {
            zs.unity.sendMessage('onFeedStatusChange', JSON.stringify(ret));
        }

        function checkTouchStart() {
            checkFeedGameNew({ type: 'feedEnter' });
        }

        if (window.tt.onFeedStatusChange) {
            zs.unity.feedStatusChange = checkFeedGameNew;
            window.tt.onFeedStatusChange(checkFeedGameNew);
        } else {
            zs.unity.feedStatusChange = checkTouchStart;
            window.tt.onTouchStart(checkTouchStart);
        }
    },

    JSOffFeedStatusChange: function () {
        if (zs.pf != 'tt') {
            return;
        }

        if (null != zs.unity.feedStatusChange) {
            return;
        }

        if (window.tt.offFeedStatusChange) {
            window.tt.offFeedStatusChange(zs.unity.feedStatusChange);
        } else {
            window.tt.offTouchStart(zs.unity.feedStatusChange);
        }
        zs.unity.feedStatusChange = null;
    },

    JSInit: function (initParam) {
        initParam = UTF8ToString(initParam);
        initParam = JSON.parse(initParam);
        if (initParam.miniGameCommon) {
            if (typeof requirePlugin === 'undefined') {
                return;
            }
            try {
                const createMiniGameCommon = requirePlugin('MiniGameCommon', {
                    enableRequireHostModule: true,
                    customEnv: {
                        wx,
                    },
                }).default;
                const miniGameCommon = createMiniGameCommon();
                if (typeof miniGameCommon === 'undefined' || typeof miniGameCommon.canIUse === 'undefined') {
                    console.error('miniGameCommon create error');
                } else {
                    window.zs.unity.miniGameCommon = miniGameCommon;
                }
            } catch (e) {
                console.error('miniGameCommon create error= ' + e);
            }
        }
        if (initParam.tdAppKey && initParam.tdAppKey != '') {
            window.tdAppSdk && window.tdAppSdk.init({
                versionCode: 1,
                versionName: initParam.versionName,
                displayName: initParam.displayName,
                appKey: initParam.tdAppKey,
                channel: initParam.channel
            });
        }
    },

    JSGetChannel: function () {
        var str;
        switch (zs.pf) {
            case 'bili':
                str = 'bilibili小游戏';
                break;
            case 'ks':
                str = '快手小游戏';
                break;
            case 'tt':
                str = '抖音小游戏';
                break;
            case 'wx':
                str = '微信小游戏';
                break;
            default:
                str = '网页';
        }
        return window.zs.unity.str2utf8(str);
    },

    JSGetSystemInfoSync: function () {
        if (null == zs.unity.systemInfoStr) {
            if (null == zs.env) {
                let version = '1.0.0';
                let versionCode = 0;
                if (window.location && window.location.pathname) {
                    const pathname = window.location.pathname;
                    let pathnameArr = pathname.split('/');
                    for (let i = pathnameArr.length - 1; i >= 0; i--) {
                        if ('' == pathnameArr[i] || isNaN(pathnameArr[i])) {
                            continue;
                        }
                        var versionStr = pathnameArr[i] + '';
                        version = `${versionStr.substring(0, 1)}.${versionStr.substring(1, 4)}.${versionStr.substring(4, 7)}`
                        versionCode = Number(versionStr.substring(7, 10));
                        break;
                    }
                }
                let language = window.navigator && window.navigator.language || '';
                let os = window.navigator && window.navigator.platform || '';
                let osVersion = window.navigator && window.navigator.appVersion || '';
                let windowSize = { width: window.innerWidth || 0, height: window.innerHeight || 0 };
                let safeArea = { height: 0 };
                let systemInfo = {
                    language,
                    statusBarHeight: 0,
                    appName: '',
                    packageName: '',
                    version,
                    versionCode,
                    imei: 'web',
                    androidId: '',
                    ip: '0.0.0.0',
                    mac: '0.0.0.0',
                    oaid: 'web',
                    platform: os,
                    system: osVersion,
                    brand: '',
                    model: '',
                };
                systemInfo.windowWidth = windowSize.width;
                systemInfo.windowHeight = windowSize.height;
                systemInfo.screenWidth = windowSize.width;
                systemInfo.screenHeight = windowSize.height;
                if (safeArea.height && safeArea.height < systemInfo.screenHeight) {
                    systemInfo.statusBarHeight = (safeArea.height / systemInfo.screenHeight) * systemInfo.screenHeight;
                }
                zs.unity.systemInfoStr = JSON.stringify(systemInfo);
            } else {
                zs.unity.systemInfoStr = JSON.stringify(zs.env.getSystemInfoSync());
            }
        }
        return window.zs.unity.str2utf8(zs.unity.systemInfoStr);
    },

    JSGetLaunchOptionsSync: function () {
        if (null == zs.unity.launchOptionsStr) {
            if (null == zs.env) {
                zs.unity.launchOptionsStr = JSON.stringify({ query: {} });
            } else {
                if (zs.pf === 'ks') {
                    const data = zs.env.getLaunchOptionsSync();
                    data.scene = data.from;
                    zs.unity.launchOptionsStr = JSON.stringify(data);
                } else {
                    zs.unity.launchOptionsStr = JSON.stringify(zs.env.getLaunchOptionsSync());
                }
            }
        }
        return window.zs.unity.str2utf8(zs.unity.launchOptionsStr);
    },

    JSGetAccountInfoSync: function () {
        if (null == zs.unity.accountInfoStr) {
            if (null == zs.env) {
                zs.unity.accountInfoStr = JSON.stringify({
                    miniProgram: {
                        envVersion: 'release',
                        appId: '',
                        version: '1.0.0'
                    }
                });
            } else if (zs.pf == 'wx') {
                zs.unity.accountInfoStr = JSON.stringify(zs.env.getAccountInfoSync());
            } else if (zs.pf == 'tt') {
                const miniProgram = {};
                const launchOptions = zs.env.getLaunchOptionsSync();
                if (launchOptions && launchOptions.extra) {
                    miniProgram.version = launchOptions.extra.mpVersion;
                    miniProgram.appId = launchOptions.extra.appId;
                }
                if (zs.env.getEnvInfoSync) {
                    const envInfo = zs.env.getEnvInfoSync();
                    const envType = envInfo.microapp.envType;
                    if ('production' === envType) {
                        miniProgram.envVersion = 'release';
                    } else if ('development' === envType) {
                        miniProgram.envVersion = 'trial';
                    } else if ('preview' === envType) {
                        miniProgram.envVersion = 'develop';
                    } else {
                        miniProgram.envVersion = envType;
                    }
                }
                zs.unity.accountInfoStr = JSON.stringify({ miniProgram });
            } else if (zs.pf === 'ks') {
                let miniProgram = {};
                const systemInfoSync = zs.env.getSystemInfoSync();
                if (systemInfoSync.host) {
                    miniProgram.appId = systemInfoSync.host.appId;
                    miniProgram.version = systemInfoSync.host.gameVersion || systemInfoSync.host.version;
                }
                miniProgram.envVersion = 'release';
                zs.unity.accountInfoStr = JSON.stringify({ miniProgram });
            } else {
                zs.unity.accountInfoStr = JSON.stringify({
                    miniProgram: {
                        appId: '',
                        envVersion: 'release'
                    }
                });
            }
        }
        return window.zs.unity.str2utf8(zs.unity.accountInfoStr);
    },

    JSVibrateShort: function () {
        if (null == zs.env) {
            if (window.navigator && window.navigator.vibrate) {
                window.navigator.vibrate(15);
            }
        }
        zs.env.vibrateShort();
    },

    JSVibrateLong: function () {
        if (null == zs.env) {
            if (window.navigator && window.navigator.vibrate) {
                window.navigator.vibrate(400);
            }
        }
        zs.env.vibrateLong();
    },

    JSShowModal: function (title, content) {
        title = UTF8ToString(title);
        content = UTF8ToString(content);
        if (null == zs.env) {
            console.log("showModal, title= " + title + ", content= " + content);
            return;
        }
        zs.env.showModal({
            title,
            content
        });
    },

    JSSetStorageSync: function (key, data) {
        key = UTF8ToString(key);
        data = UTF8ToString(data);
        if (null == zs.env) {
            window.localStorage && window.localStorage.setItem(key, data);
            return;
        }
        zs.env.setStorageSync(key, data);
    },

    JSGetStorageSync: function (key) {
        key = UTF8ToString(key);
        var str;
        if (null == zs.env) {
            str = window.localStorage && window.localStorage.getItem(key);
        } else {
            str = zs.env.getStorageSync(key);
        }
        return window.zs.unity.str2utf8(str);
    },


    JSLogin: function (uuid) {
        uuid = UTF8ToString(uuid);
        if (null == zs.env) {
            zs.unity.sendMessage("onLoginSuccess", {
                uuid,
                pf: 'Editor',
                code: 0,
                is_old: 1
            });
            return;
        }
        zs.env.login({
            force: true,
            success: (res) => {
                zs.unity.sendMessage("onLoginSuccess", {
                    uuid,
                    pf: zs.pf,
                    code: res.code,
                    is_old: 1
                });
            },
            fail: (e) => {
                zs.unity.sendMessage("onLoginFail", {
                    uuid,
                    errCode: e.errCode,
                    errMsg: e.errMsg
                });
            }
        });
    },

    JSAccessSync: function (path) {
        path = UTF8ToString(path);
        if (null == zs.env) {
            return false;
        }
        if (null == zs.fileSystemManager) {
            zs.fileSystemManager = zs.env.getFileSystemManager();
        }
        try {
            zs.fileSystemManager.accessSync(path);
            return true;
        } catch (e) {
            return false;
        }
    },

    JSMkdirSync: function (path, recursive) {
        path = UTF8ToString(path);
        if (null == zs.env) {
            return;
        }
        if (null == zs.fileSystemManager) {
            zs.fileSystemManager = zs.env.getFileSystemManager();
        }
        try {
            zs.fileSystemManager.mkdirSync(path, recursive);
            return true;
        } catch (e) {
            return false;
        }
    },

    JSReadFileSync: function (path) {
        path = UTF8ToString(path);
        if (null == zs.env) {
            return '';
        }
        if (null == zs.fileSystemManager) {
            zs.fileSystemManager = zs.env.getFileSystemManager();
        }
        var str = zs.fileSystemManager.readFileSync(path, 'utf-8');
        return window.zs.unity.str2utf8(str);
    },

    JSWriteFileSync: function (path, data) {
        path = UTF8ToString(path);
        data = UTF8ToString(data);
        if (null == zs.env) {
            return '';
        }
        if (null == zs.fileSystemManager) {
            zs.fileSystemManager = zs.env.getFileSystemManager();
        }
        try {
            zs.fileSystemManager.writeFileSync(path, data);
        } catch (e) {
            console.error('writeFileSync error=' + e);
        }
    },

    JSCreateInterstitialAd: function (adUnitId) {
        adUnitId = UTF8ToString(adUnitId);
        if (null == zs.env) {
            return window.zs.unity.str2utf8('');
        }
        let uuid = '2' + Object.keys(zs.unity.ads).length;
        zs.unity.ads[uuid] = zs.env.createInterstitialAd({
            adUnitId
        });
        if (null == zs.unity.ads[uuid]) {
            return window.zs.unity.str2utf8('');
        }
        zs.unity.ads[uuid].onError((e) => {
            console.log('adUnitId=' + adUnitId + ' error=' + e);
        });
        zs.unity.ads[uuid].onClose((res) => {
            zs.unity.sendMessage("onAdClose", {
                uuid
            });
        });
        return window.zs.unity.str2utf8(uuid);
    },
    JSCreateRewardedVideoAd: function (adUnitId) {
        adUnitId = UTF8ToString(adUnitId);
        if (null == zs.env) {
            return window.zs.unity.str2utf8('');
        }
        let uuid = '3' + Object.keys(zs.unity.ads).length;
        zs.unity.ads[uuid] = zs.env.createRewardedVideoAd({
            adUnitId
        });
        if (null == zs.unity.ads[uuid]) {
            return window.zs.unity.str2utf8('');
        }
        zs.unity.ads[uuid].onError((e) => {
            console.log('adUnitId=' + adUnitId + ' error=' + e);
        });
        zs.unity.ads[uuid].onClose((res) => {
            const isEnded = res.isEnded;
            zs.unity.sendMessage("onAdClose", {
                uuid,
                isEnded
            });
        });
        return window.zs.unity.str2utf8(uuid);
    },

    JSLoadAd: function (uuid) {
        uuid = UTF8ToString(uuid);
        if (!zs.unity.ads[uuid]) {
            return;
        }
        zs.unity.ads[uuid].load().then(() => {
            zs.unity.sendMessage("onAdLoadSuccess", {
                uuid
            });
        }).catch((e) => {
            zs.unity.sendMessage("onAdLoadFail", {
                uuid,
                errCode: e.errCode,
                errMsg: e.errMsg
            });
        });
    },

    JSShowAd: function (uuid) {
        uuid = UTF8ToString(uuid);
        if (!zs.unity.ads[uuid]) {
            return;
        }
        zs.unity.ads[uuid].show().then(() => {
            zs.unity.sendMessage("onAdShowSuccess", {
                uuid
            });
        }).catch((e) => {
            zs.unity.sendMessage("onAdShowFail", {
                uuid,
                errCode: e.errCode,
                errMsg: e.errMsg
            });
        });
    },

    JSGetUserLabel: function (uuid, data) {
        uuid = UTF8ToString(uuid);
        data = UTF8ToString(data);
        data = JSON.parse(data);
        window.zs.unity.miniGameCommon && window.zs.unity.miniGameCommon.getUserLabel(data).then((res) => {
            var msg = JSON.stringify(res);
            zs.unity.sendMessage("onGetUserLabel", {
                uuid,
                msg
            });
        }).catch(e => {
            var msg = typeof e === 'string' ? e : e ? JSON.stringify(e) : '未知错误';
            console.error('微信广告数据预测失败：' + msg);
        });
    },

    JSTDEvent: function (event, properties) {
        if (!window.tdAppSdk) {
            return;
        }
        event = UTF8ToString(event);
        properties = UTF8ToString(properties);
        params = JSON.parse(properties);
        if (event == 'register' || event == 'login') {
            window.tdAppSdk.setOpenId(params.openId);
            window.tdAppSdk.profile[event](params);
            return;
        }
        window.tdAppSdk.event({
            id: event,
            params
        });
    }
});